[单片机框架][bsp层][cx32l003][bsp

您所在的位置:网站首页 gpio debounce [单片机框架][bsp层][cx32l003][bsp

[单片机框架][bsp层][cx32l003][bsp

2024-07-09 22:48| 来源: 网络整理| 查看: 265

GPIO(general purpose intput output)是通用输入输出端口的简称,可以通过软件来控制其输入和输出。51 单片机芯片的 GPIO 引脚与外部设备连接起来,从而实现与外部通讯、 控制以及数据采集的功能。过 GPIO 最简单的应用还属点亮 LED 灯了,只需通过软件控制 GPIO 输出高低电平即可。当然GPIO 还可以作为输入控制,比如在引脚上接入一个按键,通过电平的高低判断按键是否按下。

通用输入/输出口用于芯片和外部进行数据传输,共有 4 组 GPIO:GPIOA、GPIOB、GPIOC 和GPIOD。4 组 GPIO 的功能基本相同,可以通过配置将 GPIO 映射到对应芯片引脚,每个引脚可以被独立配置为数字输入或者输出口,也可以被配置为模拟输入。另外,还可以配置成外部中断、片上外设输入/输出等复用功能。同一时刻一个引脚仅可被映射一个复用功能,通过端口复用功能寄存器(GPIOx_AFR)配置。

每个通用 I/O 口都有 5 个配置寄存器(GPIOx_DIRCR、GPIOx_OTYPER、GPIOx_PUPDR,GPIOx_SLEWCR 和 GPIOx_DRVCR),2 个数据寄存器(GPIOx_IDR 和 GPIOx_ODR),1 个输出置位寄存器(GPIOx_ODSET),1 个输出复位寄存器(GPIOx_ODCLR)和 1 个复用功能寄存器(GPIOx_AFR)。

每个端口都可以配置成内部上拉(pull up)/下拉(pull down)的输入/输出,高阻输入(floating input),推挽输出(push-pull output),开漏输出(open drain output),增强驱动能力输出。芯片复位后端口复位为高阻输入,目的是防止芯片在异常复位时,导致外部器件产生异常动作。为了避免高阻输入而产生的漏电,用户要在芯片启动之后对端口进行相应配置(配置成内部拉高输入或者输出)。端口被配成模拟端口后,数字功能被隔离,不能输出数字“1”和“0” ,CPU 读取端口的结果为“0” 。

所有端口都可以提供外部中断, 并且每个中断都可以配置成高电平触发、 低电平触发、 上升沿触发、下降沿触发或者任意边沿触发,支持边沿模式下的输入消抖。支持在工作模式/睡眠模式/深度睡眠模式下产生中断。

/******************************************************************************** * @file bsp_gpio.c * @author jianqiang.xue * @version V1.0.0 * @date 2021-04-09 * @brief gpio初始化 ********************************************************************************/ /* Includes ------------------------------------------------------------------*/ #include #include #include "RTE_Components.h" #include CMSIS_device_header #include "bsp_exti.h" #include "bsp_gpio.h" /* Private Includes ----------------------------------------------------------*/ #include "business_gpio.h" #include "business_function.h" /* Private Variables ---------------------------------------------------------*/ /* Private Function Prototypes -----------------------------------------------*/ static uint8_t get_exti_event(bsp_gpio_exti_int_event_t exti_type) { if (BSP_GPIO_EXTI_INT_LOWFALL == exti_type) { return GPIO_EXTI_INT_LOWFALL; } else if (BSP_GPIO_EXTI_INT_HIGHRISE == exti_type) { return GPIO_EXTI_INT_HIGHRISE; } else if (BSP_GPIO_EXTI_INT_FALLRISE == exti_type) { return GPIO_EXTI_INT_FALLRISE; } else { return GPIO_EXTI_INT_FALLRISE; } } /* Public Function Prototypes ------------------------------------------------*/ /** * @brief [反初始化] 关闭指定引脚功能(恢复为浮空输入) * @note NULL * @param *gpiox: gpio组号(GPIOA/GPIOB/GPIOC/GPIOD等等) * @param pin: 引脚号 * @retval None */ void bsp_gpio_deinit(void *gpiox, uint8_t pin) { HAL_GPIO_DeInit(gpiox, pin); } /** * @brief [初始化] 引脚设置为输出模式 * @note NULL * @param *gpiox: gpio组号(GPIOA/GPIOB/GPIOC/GPIOD等等) * @param pin: 引脚号 * @param out_mode: BSP_GPIO_PIN_OUT_OD 开漏输出, BSP_GPIO_PIN_OUT_PP 推免输出, BSP_GPIO_PIN_AF_OD 复用开漏, BSP_GPIO_PIN_AF_PP 复用推免 * @retval None */ void bsp_gpio_init_output(void *gpiox, uint8_t pin, bsp_gpio_pin_out_t out_mode) { volatile GPIO_InitTypeDef gpio_init_struct; gpio_init_struct.Pin = pin; gpio_init_struct.Pull = GPIO_NOPULL; gpio_init_struct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE; // 禁止输入去抖动 gpio_init_struct.SlewRate = GPIO_SLEW_RATE_HIGH; gpio_init_struct.DrvStrength = GPIO_DRV_STRENGTH_HIGH; if (out_mode == BSP_GPIO_PIN_OUT_OD) { gpio_init_struct.Mode = GPIO_MODE_OUTPUT; gpio_init_struct.OpenDrain = GPIO_OPENDRAIN; } else if (out_mode == BSP_GPIO_PIN_OUT_PP) { gpio_init_struct.Mode = GPIO_MODE_OUTPUT; gpio_init_struct.OpenDrain = GPIO_PUSHPULL; } else if (out_mode == BSP_GPIO_PIN_AF_OD) { gpio_init_struct.Mode = GPIO_MODE_AF; gpio_init_struct.OpenDrain = GPIO_OPENDRAIN; } else if (out_mode == BSP_GPIO_PIN_AF_PP) { gpio_init_struct.Mode = GPIO_MODE_AF; gpio_init_struct.OpenDrain = GPIO_PUSHPULL; } HAL_GPIO_Init(gpiox, (GPIO_InitTypeDef *)&gpio_init_struct); } /** * @brief [初始化] 引脚设置为输入模式 * @note NULL * @param *gpiox: gpio组号(GPIOA/GPIOB/GPIOC/GPIOD等等) * @param pin: 引脚号 * @param pull: BSP_GPIO_PIN_NOPULL 无上下拉, BSP_GPIO_PIN_PULLUP 上拉输入, BSP_GPIO_PIN_PULLDOWN 下拉输入 * @retval None */ void bsp_gpio_init_input(void *gpiox, uint8_t pin, bsp_gpio_pin_pull_t pull) { volatile GPIO_InitTypeDef gpio_init_struct; gpio_init_struct.Pin = pin; gpio_init_struct.Pull = pull; gpio_init_struct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE; // 禁止输入去抖动 gpio_init_struct.SlewRate = GPIO_SLEW_RATE_HIGH; gpio_init_struct.DrvStrength = GPIO_DRV_STRENGTH_HIGH; gpio_init_struct.Mode = GPIO_MODE_INPUT; HAL_GPIO_Init(gpiox, (GPIO_InitTypeDef *)&gpio_init_struct); } static uint8_t get_exti_type(bsp_gpio_exti_int_type_t exti_type) { if (BSP_GPIO_EXTI_INT_LEVEL == exti_type) { return GPIO_EXTI_INT_LEVEL; } else { return GPIO_EXTI_INT_EDGE; } } /** * @brief [初始化] 引脚设置为[输入+中断]模式 * @note NULL * @param *gpiox: gpio组号(GPIOA/GPIOB/GPIOC/GPIOD等等) * @param pin: 引脚号 * @param irqn: 中断号(在typedef enum IRQn中,例如:USART1_IRQn) * @param exti_type: BSP_GPIO_EXTI_INT_LEVEL 电平触发, BSP_GPIO_EXTI_INT_EDGE 边沿触发 * @param exti_event: BSP_GPIO_EXTI_INT_LOWFALL 低电平触发(下降沿), BSP_GPIO_EXTI_INT_HIGHRISE 高电平触发(上降沿), BSP_GPIO_EXTI_INT_FALLRISE 高低电平触发或任意电平变化 * @param pull: BSP_GPIO_PIN_NOPULL 无上下拉, BSP_GPIO_PIN_PULLUP 上拉输入, BSP_GPIO_PIN_PULLDOWN 下拉输入 * @retval None */ void bsp_gpio_init_input_exit(void *gpiox, uint8_t pin, uint8_t irqn, bsp_gpio_exti_int_type_t exti_type, bsp_gpio_exti_int_event_t exti_event, bsp_gpio_pin_pull_t pull) { volatile GPIO_InitTypeDef gpio_init_struct; gpio_init_struct.Pin = pin; gpio_init_struct.Pull = pull; gpio_init_struct.Debounce.Enable = GPIO_DEBOUNCE_ENABLE; // 禁止输入去抖动 gpio_init_struct.SlewRate = GPIO_SLEW_RATE_HIGH; gpio_init_struct.DrvStrength = GPIO_DRV_STRENGTH_HIGH; /* Configure Button pin as input with External interrupt */ gpio_init_struct.Mode = EXTI_MODE; gpio_init_struct.Exti.Enable = GPIO_EXTI_INT_ENABLE; gpio_init_struct.Exti.EdgeLevelSel = get_exti_type(exti_type); gpio_init_struct.Exti.RiseFallSel = get_exti_event(exti_event); HAL_GPIO_Init(gpiox, (GPIO_InitTypeDef *)&gpio_init_struct); bsp_exit_clear_flag(gpiox, pin); /* Enable and set Button EXTI Interrupt to the lowest priority */ bsp_exit_set(irqn, PRIORITY_LOW); } /** * @brief 设置引脚电平状态 * @note NULL * @param *gpiox: gpio组号(GPIOA/GPIOB/GPIOC/GPIOD等等) * @param pin: 引脚号 * @param state: BSP_GPIO_PIN_RESET 低电平, BSP_GPIO_PIN_SET 高电平 * @retval None */ void bsp_gpio_set_pin(void *gpiox, uint8_t pin, bsp_gpio_pin_state_t state) { HAL_GPIO_WritePin(gpiox, pin, (GPIO_PinState)state); } /** * @brief 翻转引脚电平状态 * @note NULL * @param *gpiox: gpio组号(GPIOA/GPIOB/GPIOC/GPIOD等等) * @param pin: 引脚号 * @retval None */ void bsp_gpio_set_toggle(void *gpiox, uint8_t pin) { HAL_GPIO_TogglePin(gpiox, pin); } /** * @brief 得到指定gpio状态 * @note NULL * @param *gpiox: gpio组号(GPIOA/GPIOB/GPIOC/GPIOD等等) * @param pin: 引脚号 * @retval 0 -- 低电平, 1 -- 高电平 */ bool bsp_gpio_get_state(void *gpiox, uint8_t pin) { return (bool)HAL_GPIO_ReadPin(gpiox, pin); } /** * @brief 将指定引脚复用为ADC引脚(复用模拟输入) * @note NULL * @param *gpiox: gpio组号(GPIOA/GPIOB/GPIOC/GPIOD等等) * @param pin: 引脚号 * @retval None */ void bsp_gpio_init_adc(void *gpiox, uint8_t pin) { volatile GPIO_InitTypeDef gpio_init_struct; gpio_init_struct.Pin = pin; gpio_init_struct.Mode = GPIO_MODE_ANALOG; // 模拟输入 gpio_init_struct.OpenDrain = GPIO_OPENDRAIN; // 开漏输出 gpio_init_struct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE; // 禁止输入去抖动 gpio_init_struct.SlewRate = GPIO_SLEW_RATE_HIGH; // 电压转换速率 gpio_init_struct.DrvStrength = GPIO_DRV_STRENGTH_HIGH; // 驱动强度 gpio_init_struct.Pull = GPIO_NOPULL; // 无上下拉 HAL_GPIO_Init(gpiox, (GPIO_InitTypeDef *)&gpio_init_struct); } /** * @brief 初始化i2c引脚 * @note NULL * @param *gpiox: gpio组号(GPIOA/GPIOB/GPIOC/GPIOD等等) * @param pin: 引脚号 * @param arf: 复用值 * @retval None */ void bsp_gpio_init_i2c(void *gpiox, uint8_t pin, uint8_t arf) { volatile GPIO_InitTypeDef gpio_init_struct; gpio_init_struct.Pin = pin; gpio_init_struct.Mode = GPIO_MODE_AF; // GPIO端口复用功能 gpio_init_struct.OpenDrain = GPIO_OPENDRAIN; // 开漏输出 gpio_init_struct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE; // 禁止输入去抖动 gpio_init_struct.SlewRate = GPIO_SLEW_RATE_LOW; // 电压转换速率 gpio_init_struct.DrvStrength = GPIO_DRV_STRENGTH_HIGH; // 驱动强度 gpio_init_struct.Pull = GPIO_PULLUP; // 上拉 gpio_init_struct.Alternate = arf; HAL_GPIO_Init(gpiox, (GPIO_InitTypeDef *)&gpio_init_struct); } /** * @brief 初始化uart引脚 * @note NULL * @param *gpiox: gpio组号(GPIOA/GPIOB/GPIOC/GPIOD等等) * @param pin: 引脚号 * @param arf: 复用值 * @retval None */ void bsp_gpio_init_uart(void *gpiox, uint8_t pin, uint8_t arf) { volatile GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = pin; GPIO_InitStruct.Mode = GPIO_MODE_AF; GPIO_InitStruct.OpenDrain = GPIO_PUSHPULL; GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE; GPIO_InitStruct.SlewRate = GPIO_SLEW_RATE_HIGH; GPIO_InitStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Alternate = arf; HAL_GPIO_Init(gpiox, (GPIO_InitTypeDef *)&GPIO_InitStruct); } /** * @brief 初始化tim_ch引脚 * @note NULL * @param *gpiox: gpio组号(GPIOA/GPIOB/GPIOC/GPIOD等等) * @param pin: 引脚号 * @param arf: 复用值 * @retval None */ void bsp_gpio_init_tim(void *gpiox, uint8_t pin, uint8_t arf) { volatile GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = pin; GPIO_InitStruct.Mode = GPIO_MODE_AF; GPIO_InitStruct.OpenDrain = GPIO_PUSHPULL; GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE; GPIO_InitStruct.SlewRate = GPIO_SLEW_RATE_HIGH; GPIO_InitStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Alternate = arf; HAL_GPIO_Init(gpiox, (GPIO_InitTypeDef *)&GPIO_InitStruct); } /******************************************************************************** * @file bsp_gpio.h * @author jianqiang.xue * @version V1.0.0 * @date 2021-04-09 * @brief GPIO控制 ********************************************************************************/ #ifndef __BSP_GPIO_H #define __BSP_GPIO_H /* Includes ------------------------------------------------------------------*/ #include #include /* Public enum ---------------------------------------------------------------*/ /** * @brief GPIO Bit SET and Bit RESET enumeration */ typedef enum { BSP_GPIO_PIN_RESET = 0U, BSP_GPIO_PIN_SET } bsp_gpio_pin_state_t; typedef enum { BSP_GPIO_PIN_NOPULL = 0U, BSP_GPIO_PIN_PULLUP, BSP_GPIO_PIN_PULLDOWN } bsp_gpio_pin_pull_t; typedef enum { BSP_GPIO_PIN_OUT_OD = 0U, BSP_GPIO_PIN_OUT_PP, BSP_GPIO_PIN_AF_OD, BSP_GPIO_PIN_AF_PP } bsp_gpio_pin_out_t; typedef enum { BSP_GPIO_EXTI_INT_LEVEL = 0U, // 电平触发 BSP_GPIO_EXTI_INT_EDGE, // 边沿触发 } bsp_gpio_exti_int_type_t; typedef enum { BSP_GPIO_EXTI_INT_LOWFALL = 0U, // 低电平触发(下降沿) BSP_GPIO_EXTI_INT_HIGHRISE, // 高电平触发(上降沿) BSP_GPIO_EXTI_INT_FALLRISE // 高低电平触发或任意电平变化 } bsp_gpio_exti_int_event_t; /* Public Function Prototypes ------------------------------------------------*/ // 常规引脚初始化 void bsp_gpio_deinit(void *gpiox, uint8_t pin); void bsp_gpio_init_output(void *gpiox, uint8_t pin, bsp_gpio_pin_out_t out_mode); void bsp_gpio_init_input(void *gpiox, uint8_t pin, bsp_gpio_pin_pull_t pull); void bsp_gpio_init_input_exit(void *gpiox, uint8_t pin, uint8_t irqn, bsp_gpio_exti_int_type_t exti_type, bsp_gpio_exti_int_event_t exti_event, bsp_gpio_pin_pull_t pull); // 外设引脚初始化 void bsp_gpio_init_adc(void *gpiox, uint8_t pin); void bsp_gpio_init_i2c(void *gpiox, uint8_t pin, uint8_t arf); void bsp_gpio_init_uart(void *gpiox, uint8_t pin, uint8_t arf); void bsp_gpio_init_tim(void *gpiox, uint8_t pin, uint8_t arf); // 引脚控制和状态获取 void bsp_gpio_set_pin(void *gpiox, uint8_t pin, bsp_gpio_pin_state_t state); void bsp_gpio_set_toggle(void *gpiox, uint8_t pin); bool bsp_gpio_get_state(void *gpiox, uint8_t pin); #endif


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3